package com.bluezone.dec.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bluezone.dec.common.CacheConstant;
import com.bluezone.dec.common.CodeEnum;
import com.bluezone.dec.common.SystemConstant;
import com.bluezone.dec.configuration.AppConfig;
import com.bluezone.dec.system.service.EnterpriseService;
import com.bluezone.dec.utils.RestUtils;
import com.c503.sc.utils.basetools.C503PropertiesUtils;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description 企业信息实现层
 * @Author chenzhaoming
 * @CreateDate 2018/11/6 11:38
 * @Company 浙江航天恒嘉数据科技有限公司
 */
@Service
public class EnterpriseServiceImpl implements EnterpriseService {

    private static Logger log = LoggerFactory.getLogger(EnterpriseServiceImpl.class);

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private RestUtils restUtils;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取企业列表
     *
     * @return
     */
    @Override
    public JSONArray getAllEnterprise() {
        /*查看企业列表是否在缓存中*/
        if (Strings.isNullOrEmpty(redisTemplate.opsForValue().get(CacheConstant.ENTERPRISE_LIST))) {
            String apiUrl = "";
            try {
                apiUrl = appConfig.getDseIp() + C503PropertiesUtils.getValue(SystemConstant.API_PROPERTIES,
                        "getAllEnterprise");
            } catch (Exception e) {
                log.warn(CodeEnum.NO_PATH_IN_PROPERTIES.getMsg(), e);
            }
            JSONArray enterpriseList = restUtils.doGet(apiUrl);
            /*设置企业列表缓存*/
            redisTemplate.opsForValue().set(CacheConstant.ENTERPRISE_LIST,
                    JSON.toJSONString(enterpriseList), appConfig.getEnterpriseDataCacheTime(), TimeUnit.SECONDS);
        }
        return JSON.parseObject(redisTemplate.opsForValue().get(CacheConstant.ENTERPRISE_LIST), JSONArray.class);
    }

    /**
     * 获取企业相关信息并进行缓存
     *
     * @return
     */
    @Override
    public JSONArray getEnterpriseInfo(String cacheKey) {
        if (Strings.isNullOrEmpty(redisTemplate.opsForValue().get(cacheKey))) {
            String apiUrl = "";
            try {
                apiUrl = appConfig.getDseIp() + C503PropertiesUtils.getValue(SystemConstant.API_PROPERTIES,
                        cacheKey);
            } catch (Exception e) {
                log.warn(CodeEnum.NO_PATH_IN_PROPERTIES.getMsg(), e);
            }
            JSONArray enterpriseInfoList = restUtils.doGet(apiUrl);
            /*设置企业基本信息*/
            redisTemplate.opsForValue().set(cacheKey,
                    JSON.toJSONString(enterpriseInfoList), appConfig.getEnterpriseDataCacheTime(), TimeUnit.SECONDS);
        }
        return JSON.parseObject(redisTemplate.opsForValue().get(cacheKey), JSONArray.class);
    }

    /**
     * 获取企业的规模等级.或者企业规模，或者监管层级的集合
     *
     * @param level 所需统计企业规模等级的字段名
     * @return
     */
    @Override
    public List<String> getLevel(String level) {
        List<JSONObject> enterpriseBaseList = getEnterpriseInfo(SystemConstant.BASE).toJavaList(JSONObject.class);

        if (StringUtils.isEmpty(enterpriseBaseList)) {
            return new ArrayList<>();
        }

        return enterpriseBaseList.stream().filter(baseListStream -> {
            JSONObject base = baseListStream.getJSONObject(SystemConstant.BASE);
            return (null != base && !Strings.isNullOrEmpty(base.getString(level)));
        }).map(baseListStream -> baseListStream.getJSONObject(SystemConstant.BASE).getString(level))
                .distinct().collect(Collectors.toList());
    }

    /**
     * 获取全部企业的重大危险源信息列表
     *
     * @return
     */
    @Override
    public List<JSONObject> importantDangerInfoList() {
        List<JSONObject> enterpriseSecurityList = getEnterpriseInfo(CacheConstant.ENTERPRISE_SECURITY).toJavaList(JSONObject.class);

        if (StringUtils.isEmpty(enterpriseSecurityList)) {
            return new ArrayList<>();
        }

        int i;
        int listSize = enterpriseSecurityList.size();
        List<JSONObject> importantDangerInfoList = new ArrayList<>();
        for (i = 0; i < listSize; i++) {
            importantDangerInfoList.addAll(Optional.ofNullable(enterpriseSecurityList.get(i).getJSONObject(SystemConstant.SECURITY))
                    .map(security -> security.getJSONObject("dangerChemicalsIndustryInfo"))
                    .map(danger -> danger.getJSONArray("importantDangerInfoList").toJavaList(JSONObject.class))
                    .orElse(new ArrayList<>()));
        }
        return importantDangerInfoList;
    }

    /**
     * 获取某个企业的行业类型,规模等级.或者企业规模，或者监管层级
     *
     * @param creditCode
     * @return
     */
    @Override
    public String getIndustryType(String creditCode, String level, List<JSONObject> baseEnterpriseList) {
        int i;
        int listSize = baseEnterpriseList.size();
        String typeValue = "";

        if (listSize != 0) {

            for (i = 0; i < listSize; i++) {
                if ((!StringUtils.isEmpty(baseEnterpriseList)) && creditCode.equals(baseEnterpriseList.get(i).getString(SystemConstant.ENTERPRISE_CODE))) {
                    typeValue = Optional.ofNullable(baseEnterpriseList.get(i).getJSONObject(SystemConstant.BASE))
                            .map(base -> base.getString(level))
                            .orElse("");
                    break;
                }
            }
            return typeValue;
        }

        return typeValue;
    }

    /**
     * 统计所有的活动类型
     * 统计所有可能引发的事故类型
     * 重大危险源所有的级别
     *
     * @return
     */
    @Override
    public List<String> getType(String type) {
        /*获取全部的重大危险源信息列表*/
        List<JSONObject> importantDangerInfoList = importantDangerInfoList();

        if (StringUtils.isEmpty(importantDangerInfoList)) {
            return new ArrayList<>();
        }

        return importantDangerInfoList.stream().filter(importantDangerInfo -> !Strings.isNullOrEmpty(importantDangerInfo.getString(type)))
                .map(importantDangerInfo -> importantDangerInfo.getString(type)).distinct().collect(Collectors.toList());
    }

    /**
     * 统计重点监管企业的数量
     *
     * @return
     */
    @Override
    public long dangerChemistry() {
        List<JSONObject> enterpriseSecurityList = getEnterpriseInfo(CacheConstant.ENTERPRISE_SECURITY).toJavaList(JSONObject.class);

        if (StringUtils.isEmpty(enterpriseSecurityList)) {
            return 0;
        }

        return enterpriseSecurityList.stream().filter(jsonObject ->
                Optional.ofNullable(jsonObject.getJSONObject(SystemConstant.SECURITY))
                        .map(security -> security.getJSONObject("summary"))
                        .map(summary -> summary.getJSONObject("dangerCharacteristics"))
                        .map(danger -> danger.getBoolean("involvedFocusDangerChemistry"))
                        .orElse(false)).count();
    }

    /**
     * 获取所有的重大危险源企业
     *
     * @return
     */
    @Override
    public List<JSONObject> dangerEnterprise() {
        List<JSONObject> enterpriseSecurityList = getEnterpriseInfo(CacheConstant.ENTERPRISE_SECURITY).toJavaList(JSONObject.class);

        if (StringUtils.isEmpty(enterpriseSecurityList)) {
            return new ArrayList<>();
        }

        return enterpriseSecurityList.stream().filter(enterpriseSecurity ->
                Optional.ofNullable(enterpriseSecurity.getJSONObject(SystemConstant.SECURITY))
                        .map(security -> security.getJSONObject("summary"))
                        .map(summary -> summary.getJSONObject("dangerCharacteristics"))
                        .map(danger -> danger.getBoolean("dangerSource"))
                        .orElse(false)
        ).collect(Collectors.toList());
    }
}
